class WeaDragChoose extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dragStart: false,
            startRow: -1,
            startColumn: -1,
            endRow: -1,
            endColumn: -1
        };
        this.activeCellProps = [];
    }
    render() {
        this.activeCellProps = [];
        return (
            <span>
                {this.registerChildren(this.props.children)}
            </span>
        );
    }
    
    registerChildren = (children) => {
        if (typeof children !== 'object' || children === null) {
            return children;
        }
        let childrenCount = React.Children.count(children);
        if (childrenCount > 1) {
            return React.Children.map(children, child => this.registerChild(child));
        } else if (childrenCount === 1) {
            return this.registerChild(Array.isArray(children) ? children[0] : children);
        }
    }
    registerChild = (child) => {
        if (typeof child !== 'object' || child === null) {
            return child;
        }
        
        if (child.props && Array.isArray(child.props.itemPosition)) {
            let props = child.props;
            let pos = props.itemPosition;
            let newProps = {
                onMouseUp:this.mouseUp.bind(this,pos,props),
                onTouchEnd:this.mouseUp.bind(this,pos,props),
                onMouseDown: this.mouseDown.bind(this,pos,props),
                onTouchStart: this.mouseDown.bind(this, pos, props),
                onMouseMove: this.mouseMove.bind(this,pos,props),
                onTouchMove: this.mouseMove.bind(this, pos, props),
            };
            if (this.checkActive(pos, props)) {
                this.activeCellProps.push(props);
                if (this.props.activeClass) {
                   newProps.className = (props.className || '') + ' ' + this.props.activeClass;
                }
                if (this.props.activeStyle) {
                    newProps.style = {...props.style, ...this.props.activeStyle};
                }
            };
            let newEle = React.cloneElement(child, newProps);
            return newEle;
        }
        return React.cloneElement(child, {}, this.registerChildren(child.props && child.props.children));
    }
    
    mouseUp = (pos, props, e) => {
        if (!this.state.dragStart) return;
        this.setState({
            dragStart: false,
            endRow: pos[0],
            endColumn: pos[1],
            endProps: props
        }, () => {
            this.props.onSelectEnd && this.props.onSelectEnd({...this.state}, this.activeCellProps);
        });
    }
    
    mouseDown = (pos,props,e) => {
        this.setState({
            dragStart: true,
            startRow: pos[0],
            startColumn: pos[1],
            endRow: pos[0],
            endColumn: pos[1],
            startProps: props,
            endProps: props
        }, () => {
            this.props.onSelect && this.props.onSelect({...this.state}, this.activeCellProps)
        });
    }
    
    mouseMove = (pos,props,e) => {
        let {dragStart} = this.state;
        if (!dragStart) return;
        e.preventDefault();
        let endRow = pos[0], endColumn = pos[1];
        this.setState({endRow, endColumn, endProps: props}, () => {
            this.props.onSelect && this.props.onSelect({...this.state}, this.activeCellProps)
        });
    }
    
    checkActive(itemPos, props) {
        let {startRow, startColumn, endRow, endColumn} = this.state;
        let minRow = Math.min(startRow, endRow),
            maxRow = Math.max(startRow, endRow),
            minColumn = Math.min(startColumn, endColumn),
            maxColumn = Math.max(startColumn, endColumn);
        if (this.props.checkActive) {
            let checkObject = {...this.state, minRow, minColumn, maxRow, maxColumn};
            return this.props.checkActive(props, checkObject)
        }
        return itemPos[0] >= minRow && itemPos[0] <= maxRow && itemPos[1] >= minColumn && itemPos[1] <= maxColumn;
    }
    
    clear() {
        this.setState({
            dragStart: false,
            startRow: -1,
            startColumn: -1,
            endRow: -1,
            endColumn: -1
        });
    }
}

/*const getCellLocation = (pos, e) => {
 let b;
 if (e.touches) {
 let c = e.touches[0];
 b = document.elementFromPoint(c.clientX, c.clientY);
 } else {
 for (b = e.target; "TD" !== b.tagName; ) {
 b = b.parentNode;
 }
 }
 return { row: b.parentNode.rowIndex, column: b.cellIndex };
 }*/

/**
 * 使用方式如下：
 * 在支持拖拽选中的区域外包一层 WeaDragChoose，支持选中的子节点需要传入itemPosition属性。onSelect为拖拽时触发方法，onSelectEnd为拖拽结束触发方法。
 * itemPosition为数组:[行号,列号];
 * onSelect与onSelectEnd会返回开始的行、列，结束的行列
 */

WeaDragChoose.propTypes = {
    onSelect: React.PropTypes.func,
    onSelectEnd: React.PropTypes.func,
    checkActive: React.PropTypes.func//判断表格是否选中（激活active状态）的方法,不会改变onSelect/onSelectEnd回调。
};

export default WeaDragChoose;